import datetime

import coin.exchange.bybit.kr_rest.exp_util as exp_util
from coin.exchange.base.kr_rest.derivative_util import (PERPETUAL_DATE)
from coin.exchange.bybit.kr_rest.constants import (
  quarter_contract_date, contract_type_list)


def find_contract_type_from_expiry(current_datetime, expiry):
  if expiry == PERPETUAL_DATE:
    return 'perpetual'
  expiry = exp_util.expiry_accurate_datetime(expiry)
  time_delta = expiry - current_datetime
  assert time_delta > datetime.timedelta()
  if expiry == find_expiry_from_contract_type(current_datetime, 'quarter'):
    return 'quarter'
  elif expiry == find_expiry_from_contract_type(current_datetime, 'next_quarter'):
    return 'next_quarter'
  else:
    raise ValueError(current_datetime, expiry)


def find_expiry_from_contract_type(current_datetime, contract_type):
  if contract_type == 'perpetual':
    return PERPETUAL_DATE
  assert contract_type in contract_type_list
  if contract_type == 'quarter':
    return exp_util.find_quarter_contract_expiring_date(
        quarter_contract_date, current_datetime)
  elif contract_type == 'next_quarter':
    return exp_util.find_next_quarter_contract_expiring_date(
        quarter_contract_date, current_datetime)
  else:
    raise ValueError(current_datetime, contract_type)


def to_expiry_contract_type(expiry_str, current_datetime):
  if expiry_str == 'perpetual':
    expiry = PERPETUAL_DATE
    contract_type = 'perpetual'
  elif expiry_str in contract_type_list:
    contract_type = expiry_str
    expiry = find_expiry_from_contract_type(current_datetime, contract_type)
  elif expiry_str.isdigit():
    expiry = datetime.datetime.strptime(expiry_str, '%Y%m%d')
    contract_type = find_contract_type_from_expiry(current_datetime, expiry)
  else:
    raise ValueError(expiry_str, current_datetime)
  return expiry, contract_type


def parse_native_expiry_contract_type(expiry_str, current_datetime):
  assert isinstance(expiry_str, str)
  if expiry_str == 'PERPETUAL':
    expiry = PERPETUAL_DATE
    contract_type = 'perpetual'
  else:
    expiry = exp_util.expiry_accurate_datetime(
        datetime.datetime.strptime(expiry_str, '%Y%m%d'))
    contract_type = find_contract_type_from_expiry(current_datetime, expiry)
  return expiry, contract_type


def to_native_expiry_str(expiry, contract_type):
  if contract_type == 'perpetual':
    assert expiry == PERPETUAL_DATE
    return 'PERPETUAL'
  else:
    raise ValueError(contract_type)
